﻿Imports RapidConsole
''' <summary>
''' Represents the base class for a console program framework consisting of a command line input window, 
''' a scrollable output window, and a command method processor.
''' </summary>
Public Class CommandPromptProgram
    Inherits CommandProcessor
    Private WithEvents commandLineWindow As New CommandLineWindow
    Private WithEvents outputWindow As New OutputWindow
    Private helpWindow As HelpWindow

    ''' <summary>
    ''' Gets the command line window associated with this program.
    ''' </summary>
    ''' <returns></returns>
    Public Overridable ReadOnly Property CommandLine As CommandLineWindow
        Get
            Return commandLineWindow
        End Get
    End Property

    Public Property UseF1Help As Boolean

    ''' <summary>
    ''' Gets the command output window associated with this program.
    ''' </summary>
    ''' <returns></returns>
    Public Overridable ReadOnly Property Output As OutputWindow
        Get
            Return outputWindow
        End Get
    End Property

    ''' <summary>
    ''' Gets or sets a value which determines if the result code of an executed command is automatically
    ''' written to the output window.  Default is true.
    ''' </summary>
    ''' <returns></returns>
    Public Overridable Property WriteResultStatusToOutput As Boolean = True

    Public Sub New()
        outputWindow.Children.Add(commandLineWindow)
        helpWindow = New HelpWindow(Me)
    End Sub

    ''' <summary>
    ''' Waits for the user to press any key.
    ''' </summary>
    Public Overridable Sub PressAnyKeyToContinue()
        Console.ReadKey(True)
    End Sub

    ''' <summary>
    ''' Begins executing the program by running the associated windows.
    ''' </summary>
    Public Overridable Sub Start()
        outputWindow.Show()
        commandLineWindow.Show()
        Window.Run()
    End Sub

    Protected Overridable Sub commandLineWindow_CommandEntered(sender As Object, e As CommandLineWindow.CommandEnteredEventArgs) Handles commandLineWindow.CommandEntered
        Dim result = ExecuteCommand(e.CommandLine)
        If WriteResultStatusToOutput Then
            If result = CommandExecutionResultStatus.CUSTOM Then
                outputWindow.AppendText(lastCustomStatus, True)
            ElseIf result = CommandExecutionResultStatus.EXCEPTION
                outputWindow.AppendText($"{result}: {LastCommandError.Message}", True)
            Else
                outputWindow.AppendText(result.ToString, True)
            End If
        End If
    End Sub

    <CommandMethod("?", "Help (command)", "Displays the help information for all commands when used alone, or help for a specific command when followed by a key word.")>
    Protected Sub Help(commandLine As CommandLine)
        If commandLine.ParameterCount = 1 Then
            If ContainsCommand(commandLine.ParameterValue(0)) Then
                ShowCommandHelp(Output, commandLine.ParameterValue(0))
            End If
        Else
            For Each keyword In GetCommandKeywords()
                ShowCommandHelp(Output, keyword)
            Next
        End If
    End Sub

    Private Sub commandLineWindow_KeyProcessing(sender As Object, e As Window.KeyProcessingEventArgs) Handles commandLineWindow.KeyProcessing
        If UseF1Help Then
            If e.Key.Key = ConsoleKey.F1 Then
                helpWindow.Visible = Not helpWindow.Visible
            End If
        End If
    End Sub
End Class
